#include "circlelist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct _tag_CircleList _CircleList;

struct _tag_CircleList{
    CircleListNode head;
    CircleListNode *current;
    int length;
};



CircleList* CircleList_Create(){
    _CircleList* list=malloc(sizeof (_CircleList));
    memset(list,0,sizeof (_CircleList));
    return list;
}

void CircleList_Destroy(CircleList* list){
    if(list==NULL){
        perror("list can not be null");
        return ;
    }
    free(list);
}

void CircleList_Clear(CircleList* list){
    if(list==NULL){
        perror("list can not be null");
        return ;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
//    memset(tmp,0,sizeof(_CircleList));
    tmp->head.next=NULL;
    tmp->length=0;
    tmp->current=NULL;
}

/**
 * @brief CircleList_Insert 插入节点
 * @param list
 * @param node
 * @param pos
 * @return
 */
int CircleList_Insert(CircleList* list,CircleListNode *node,int pos){
    if(list==NULL){
        perror("list can not be null");
        return -1;
    }
    _CircleList* tmp=NULL;
    tmp=list;
    CircleListNode* tmpNode=&(tmp->head);
    //head-0->1->2->3->4
    //	   ^8<-7<-6<-5-v
    //要求下一个节点不能为null
    for(int i=0;i<pos&&tmpNode->next!=NULL;i++){
        tmpNode=tmpNode->next;
    }
    //得到目标插入的前面一个基点
    CircleListNode* afterTmp;
    afterTmp=tmpNode->next;
    node->next=afterTmp;
    tmpNode->next=node;
    //特殊情况的处理，如果tmpNode 是head节点怎么处理
    if(afterTmp==NULL){
        //自己指向自己
        node->next=node;
    }
    //第一次插入需要将slider指向当前节点
    if(tmp->length==0){
        tmp->current=node;
    }
    //头插入法
    if(pos==0){
        CircleListNode* tmpNodeE=&(tmp->head);
        for(int i=0;i<tmp->length;i++){
            tmpNodeE=tmpNodeE->next;
        }
        CircleListNode* lastNode=tmpNodeE->next;
        lastNode->next=node;
    }
    //长度自增1
    tmp->length++;


}

int CircleList_Length(CircleList* list){
    if(list==NULL){
        perror("list can not be null");
        return -1;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    return tmp->length;
}

CircleListNode* CircleList_Get(CircleList* list,int pos){
    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;

    //循环链表是可以随意取的
//    if(pos>=tmp->length){
//        perror("out of bound exception");
//        return NULL;
//    }
    CircleListNode* tmpnode=&(tmp->head);
    for(int i=0;i<pos;i++){
        tmpnode=tmpnode->next;
    }
    return tmpnode->next;

}

CircleListNode* CircleList_Delete(CircleList* list,int pos){
    //辅助指针的定义
    CircleListNode* deleteNode=NULL;
    CircleListNode* afterDelNode=NULL;
    CircleListNode* beforeDelNode=NULL;
    CircleListNode* tmpnode=NULL;
    CircleListNode* finalNode=NULL;

    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    tmpnode=&(tmp->head);
    //首先是对指针进行移动，移动到目标节点，这里我们假定我们什么都不清楚
    for(int i=0;i<pos;i++){
        tmpnode=tmpnode->next;
    }
    beforeDelNode=tmpnode;
    deleteNode=tmpnode->next;
    afterDelNode=deleteNode->next;
    //head->0 1 2 3 4
    //		1
    //如果删除的是头元素，不仅仅需要指向的修改，还需要将末尾元素重新指向
    if(pos==0){
        //拿到最后一个节点
        for(int i=0;i<tmp->length;i++){
            tmpnode=tmpnode->next;
        }
        finalNode=tmpnode;
        finalNode->next=afterDelNode;
    }
    beforeDelNode->next=afterDelNode;

    //如果游标指向的是被删除的节点
    tmp->length--;
    if(tmp->current==deleteNode){
        tmp->current=afterDelNode;
    }
    //收尾工作
    if(tmp->length==0){
        tmp->head.next=NULL;
        tmp->current=NULL;
    }
    return deleteNode;
}

CircleListNode* CircleList_Reset(CircleList* list){
    //将current 指向头节点
    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    tmp->current=tmp->head.next;
    return tmp->current;
}

CircleListNode* CircleList_Current(CircleList* list){
    //将current 指向头节点
    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    return tmp->current;
}

CircleListNode* CircleList_Next(CircleList* list){
    //将current 指向头节点
    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    if(tmp->current!=NULL){
        tmp->current=tmp->current->next;
    }
    return tmp->current;
}

CircleListNode* CircleList_DeleteNode(CircleList* list,CircleListNode *node){
    //将current 指向头节点
    int nPos=0;
    if(list==NULL){
        perror("list can not be null");
        return NULL;
    }
    _CircleList* tmp=NULL;
    tmp=(_CircleList*)list;
    CircleListNode* delNode=NULL;
    CircleListNode* tmpNode=&(tmp->head);
    for(int i=0;i<tmp->length;i++){
        if(tmpNode->next==node){
            nPos=i;
            delNode=tmpNode->next;
            break;
        }
        tmpNode=tmpNode->next;
    }

    if(delNode!=NULL){
        CircleList_Delete(list,nPos);
    }

}

